/*     */ package com.zimbra.cs.db;
/*     */ 
/*     */ import com.zimbra.common.util.Log;
/*     */ import com.zimbra.common.util.ZimbraLog;
/*     */ import com.zimbra.cs.util.Zimbra;
/*     */ import java.io.InputStream;
/*     */ import java.io.Reader;
/*     */ import java.math.BigDecimal;
/*     */ import java.net.URL;
/*     */ import java.sql.Array;
/*     */ import java.sql.Blob;
/*     */ import java.sql.Clob;
/*     */ import java.sql.Date;
/*     */ import java.sql.PreparedStatement;
/*     */ import java.sql.Ref;
/*     */ import java.sql.ResultSet;
/*     */ import java.sql.SQLException;
/*     */ import java.sql.Time;
/*     */ import java.sql.Timestamp;
/*     */ import java.util.ArrayList;
/*     */ import java.util.Calendar;
/*     */ import java.util.List;
/*     */ import org.apache.commons.dbcp.DelegatingConnection;
/*     */ import org.apache.commons.dbcp.DelegatingPreparedStatement;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ class DebugPreparedStatement
/*     */   extends DelegatingPreparedStatement
/*     */ {
/*     */   private static final int MAX_STRING_LENGTH = 1024;
/*  46 */   private static long sSlowSqlThreshold = Long.MAX_VALUE;
/*     */   
/*     */   private final PreparedStatement mStmt;
/*     */   private String mSql;
/*     */   private long mStartTime;
/*     */   
/*     */   private class AutoSizeList<E>
/*     */     extends ArrayList<E>
/*     */   {
/*     */     private AutoSizeList() {}
/*     */     
/*     */     public E set(int index, E element)
/*     */     {
/*  59 */       if (index >= size()) {
/*  60 */         for (int i = size(); i <= index; i++) {
/*  61 */           add(null);
/*     */         }
/*     */       }
/*  64 */       return (E)super.set(index, element);
/*     */     } }
/*     */   
/*  67 */   private List<Object> mParams = new AutoSizeList(null);
/*     */   
/*     */   DebugPreparedStatement(DelegatingConnection conn, PreparedStatement stmt, String sql) {
/*  70 */     super(conn, stmt);
/*  71 */     this.mStmt = stmt;
/*  72 */     this.mSql = sql;
/*     */   }
/*     */   
/*     */   public static void setSlowSqlThreshold(long millis) {
/*  76 */     ZimbraLog.sqltrace.info("Setting slow SQL threshold to %dms.", new Object[] { Long.valueOf(millis) });
/*  77 */     sSlowSqlThreshold = millis;
/*     */   }
/*     */   
/*     */   private String getSql() {
/*  81 */     if (this.mSql == null) {
/*  82 */       return null;
/*     */     }
/*  84 */     StringBuffer buf = new StringBuffer();
/*  85 */     int start = 0;
/*  86 */     int qPos = this.mSql.indexOf('?', start);
/*  87 */     int paramIndex = 1;
/*     */     
/*  89 */     while (qPos >= 0) {
/*  90 */       buf.append(this.mSql.substring(start, qPos));
/*  91 */       if (paramIndex == this.mParams.size()) {
/*  92 */         throw new IllegalStateException("Not enough parameters bound for SQL: " + this.mSql);
/*     */       }
/*  94 */       Object o = this.mParams.get(paramIndex);
/*  95 */       if (o == null) {
/*  96 */         o = "NULL";
/*  97 */       } else if ((o instanceof String))
/*     */       {
/*  99 */         String s = (String)o;
/* 100 */         if (s.indexOf('\'') >= 0) {
/* 101 */           s = s.replaceAll("'", "''");
/*     */         }
/* 103 */         o = "'" + s + "'";
/*     */       }
/* 105 */       buf.append(o);
/*     */       
/*     */ 
/* 108 */       start = qPos + 1;
/* 109 */       if (start >= this.mSql.length()) {
/*     */         break;
/*     */       }
/* 112 */       qPos = this.mSql.indexOf('?', start);
/* 113 */       paramIndex++;
/*     */     }
/*     */     
/* 116 */     if (start < this.mSql.length())
/*     */     {
/* 118 */       buf.append(this.mSql.substring(start, this.mSql.length()));
/*     */     }
/* 120 */     return buf.toString();
/*     */   }
/*     */   
/*     */   private void log() {
/* 124 */     long time = System.currentTimeMillis() - this.mStartTime;
/* 125 */     if (time > sSlowSqlThreshold) {
/* 126 */       String sql = getSql();
/* 127 */       ZimbraLog.sqltrace.info("Slow execution (%dms): %s", new Object[] { Long.valueOf(time), sql });
/* 128 */     } else if (ZimbraLog.sqltrace.isDebugEnabled()) {
/* 129 */       String sql = getSql();
/* 130 */       ZimbraLog.sqltrace.debug(sql + " - " + time + "ms" + getHashCodeString());
/*     */     }
/*     */   }
/*     */   
/*     */   private void logException(SQLException e) {
/* 135 */     if (ZimbraLog.sqltrace.isDebugEnabled()) {
/* 136 */       ZimbraLog.sqltrace.debug(e.toString() + ": " + getSql() + getHashCodeString());
/*     */     }
/*     */   }
/*     */   
/*     */   private void processDbError(SQLException e) {
/* 141 */     if (Db.errorMatches(e, Db.Error.TABLE_FULL))
/* 142 */       Zimbra.halt("DB out of space", e);
/*     */   }
/*     */   
/*     */   private String getHashCodeString() {
/* 146 */     String hashCodeString = "";
/*     */     try {
/* 148 */       hashCodeString = ", conn=" + this.mStmt.getConnection().hashCode();
/*     */     } catch (SQLException e) {
/* 150 */       ZimbraLog.sqltrace.warn("Unable to determine connection hashcode", e);
/*     */     }
/* 152 */     return hashCodeString;
/*     */   }
/*     */   
/*     */   private void startTimer() {
/* 156 */     this.mStartTime = System.currentTimeMillis();
/*     */   }
/*     */   
/*     */   public ResultSet executeQuery()
/*     */     throws SQLException
/*     */   {
/* 162 */     startTimer();
/*     */     ResultSet rs;
/*     */     try {
/* 165 */       rs = this.mStmt.executeQuery();
/*     */     } catch (SQLException e) {
/* 167 */       logException(e);
/* 168 */       processDbError(e);
/* 169 */       throw e;
/*     */     }
/* 171 */     log();
/* 172 */     return rs;
/*     */   }
/*     */   
/*     */   public int executeUpdate() throws SQLException {
/* 176 */     startTimer();
/*     */     int numRows;
/*     */     try {
/* 179 */       numRows = this.mStmt.executeUpdate();
/*     */     } catch (SQLException e) {
/* 181 */       logException(e);
/* 182 */       processDbError(e);
/* 183 */       throw e;
/*     */     }
/* 185 */     log();
/* 186 */     return numRows;
/*     */   }
/*     */   
/*     */   public void setNull(int parameterIndex, int sqlType) throws SQLException {
/* 190 */     this.mParams.set(parameterIndex, null);
/* 191 */     this.mStmt.setNull(parameterIndex, sqlType);
/*     */   }
/*     */   
/*     */   public void setBoolean(int parameterIndex, boolean x) throws SQLException {
/* 195 */     this.mParams.set(parameterIndex, Boolean.valueOf(x));
/* 196 */     this.mStmt.setBoolean(parameterIndex, x);
/*     */   }
/*     */   
/*     */   public void setByte(int parameterIndex, byte x) throws SQLException {
/* 200 */     this.mParams.set(parameterIndex, Byte.valueOf(x));
/* 201 */     this.mStmt.setByte(parameterIndex, x);
/*     */   }
/*     */   
/*     */   public void setShort(int parameterIndex, short x) throws SQLException {
/* 205 */     this.mParams.set(parameterIndex, Short.valueOf(x));
/* 206 */     this.mStmt.setShort(parameterIndex, x);
/*     */   }
/*     */   
/*     */   public void setInt(int parameterIndex, int x) throws SQLException {
/* 210 */     this.mParams.set(parameterIndex, Integer.valueOf(x));
/* 211 */     this.mStmt.setInt(parameterIndex, x);
/*     */   }
/*     */   
/*     */   public void setLong(int parameterIndex, long x) throws SQLException {
/* 215 */     this.mParams.set(parameterIndex, Long.valueOf(x));
/* 216 */     this.mStmt.setLong(parameterIndex, x);
/*     */   }
/*     */   
/*     */   public void setFloat(int parameterIndex, float x) throws SQLException {
/* 220 */     this.mParams.set(parameterIndex, Float.valueOf(x));
/* 221 */     this.mStmt.setFloat(parameterIndex, x);
/*     */   }
/*     */   
/*     */   public void setDouble(int parameterIndex, double x) throws SQLException {
/* 225 */     this.mParams.set(parameterIndex, Double.valueOf(x));
/* 226 */     this.mStmt.setDouble(parameterIndex, x);
/*     */   }
/*     */   
/*     */   public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
/* 230 */     this.mParams.set(parameterIndex, x);
/* 231 */     this.mStmt.setBigDecimal(parameterIndex, x);
/*     */   }
/*     */   
/*     */   public void setString(int parameterIndex, String x) throws SQLException {
/* 235 */     String loggedValue = x;
/* 236 */     if ((x != null) && (x.length() > 1024)) {
/* 237 */       loggedValue = loggedValue.substring(0, 1024) + "...";
/*     */     }
/* 239 */     this.mParams.set(parameterIndex, loggedValue);
/* 240 */     this.mStmt.setString(parameterIndex, x);
/*     */   }
/*     */   
/*     */   public void setBytes(int parameterIndex, byte[] x) throws SQLException {
/* 244 */     this.mParams.set(parameterIndex, "<byte[]>");
/* 245 */     this.mStmt.setBytes(parameterIndex, x);
/*     */   }
/*     */   
/*     */   public void setDate(int parameterIndex, Date x) throws SQLException {
/* 249 */     this.mParams.set(parameterIndex, x);
/* 250 */     this.mStmt.setDate(parameterIndex, x);
/*     */   }
/*     */   
/*     */   public void setTime(int parameterIndex, Time x) throws SQLException {
/* 254 */     this.mParams.set(parameterIndex, x);
/* 255 */     this.mStmt.setTime(parameterIndex, x);
/*     */   }
/*     */   
/*     */   public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
/* 259 */     this.mParams.set(parameterIndex, x);
/* 260 */     this.mStmt.setTimestamp(parameterIndex, x);
/*     */   }
/*     */   
/*     */   public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException
/*     */   {
/* 265 */     this.mParams.set(parameterIndex, "<Ascii Stream>");
/* 266 */     this.mStmt.setAsciiStream(parameterIndex, x, length);
/*     */   }
/*     */   
/*     */   public void setUnicodeStream(int parameterIndex, InputStream x, int length)
/*     */     throws SQLException
/*     */   {
/* 272 */     this.mParams.set(parameterIndex, "<Unicode Stream>");
/* 273 */     this.mStmt.setUnicodeStream(parameterIndex, x, length);
/*     */   }
/*     */   
/*     */   public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException
/*     */   {
/* 278 */     this.mParams.set(parameterIndex, "<Binary Stream>");
/* 279 */     this.mStmt.setBinaryStream(parameterIndex, x, length);
/*     */   }
/*     */   
/*     */   public void clearParameters() throws SQLException {
/* 283 */     this.mParams.clear();
/* 284 */     this.mStmt.clearParameters();
/*     */   }
/*     */   
/*     */   public void setObject(int parameterIndex, Object x, int targetSqlType, int scale) throws SQLException
/*     */   {
/* 289 */     this.mParams.set(parameterIndex, x);
/* 290 */     this.mStmt.setObject(parameterIndex, x, targetSqlType, scale);
/*     */   }
/*     */   
/*     */   public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException
/*     */   {
/* 295 */     this.mParams.set(parameterIndex, x);
/* 296 */     this.mStmt.setObject(parameterIndex, x, targetSqlType);
/*     */   }
/*     */   
/*     */   public void setObject(int parameterIndex, Object x) throws SQLException {
/* 300 */     this.mParams.set(parameterIndex, x);
/* 301 */     this.mStmt.setObject(parameterIndex, x);
/*     */   }
/*     */   
/*     */   public boolean execute() throws SQLException {
/* 305 */     startTimer();
/*     */     boolean result;
/*     */     try {
/* 308 */       result = this.mStmt.execute();
/*     */     } catch (SQLException e) {
/* 310 */       logException(e);
/* 311 */       processDbError(e);
/* 312 */       throw e;
/*     */     }
/* 314 */     log();
/* 315 */     return result;
/*     */   }
/*     */   
/*     */   public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException
/*     */   {
/* 320 */     this.mParams.set(parameterIndex, "<Character Stream>");
/* 321 */     this.mStmt.setCharacterStream(parameterIndex, reader, length);
/*     */   }
/*     */   
/*     */   public void setRef(int i, Ref x) throws SQLException {
/* 325 */     this.mParams.set(i, "<Ref>");
/* 326 */     this.mStmt.setRef(i, x);
/*     */   }
/*     */   
/*     */   public void setBlob(int i, Blob x) throws SQLException {
/* 330 */     this.mParams.set(i, "<Blob>");
/* 331 */     this.mStmt.setBlob(i, x);
/*     */   }
/*     */   
/*     */   public void setClob(int i, Clob x) throws SQLException {
/* 335 */     this.mParams.set(i, "<Clob>");
/* 336 */     this.mStmt.setClob(i, x);
/*     */   }
/*     */   
/*     */   public void setArray(int i, Array x) throws SQLException {
/* 340 */     this.mParams.set(i, "<Array>");
/* 341 */     this.mStmt.setArray(i, x);
/*     */   }
/*     */   
/*     */   public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException {
/* 345 */     this.mParams.set(parameterIndex, x);
/* 346 */     this.mStmt.setDate(parameterIndex, x, cal);
/*     */   }
/*     */   
/*     */   public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException {
/* 350 */     this.mParams.set(parameterIndex, x);
/* 351 */     this.mStmt.setTime(parameterIndex, x, cal);
/*     */   }
/*     */   
/*     */   public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException {
/* 355 */     this.mParams.set(parameterIndex, x);
/* 356 */     this.mStmt.setTimestamp(parameterIndex, x, cal);
/*     */   }
/*     */   
/*     */   public void setNull(int paramIndex, int sqlType, String typeName) throws SQLException {
/* 360 */     this.mParams.set(paramIndex, null);
/* 361 */     this.mStmt.setNull(paramIndex, sqlType, typeName);
/*     */   }
/*     */   
/*     */   public void setURL(int parameterIndex, URL x) throws SQLException {
/* 365 */     this.mParams.set(parameterIndex, x);
/* 366 */     this.mStmt.setURL(parameterIndex, x);
/*     */   }
/*     */   
/*     */   public ResultSet executeQuery(String sql) throws SQLException {
/* 370 */     this.mSql = sql;
/* 371 */     startTimer();
/*     */     ResultSet rs;
/*     */     try {
/* 374 */       rs = this.mStmt.executeQuery(sql);
/*     */     } catch (SQLException e) {
/* 376 */       logException(e);
/* 377 */       processDbError(e);
/* 378 */       throw e;
/*     */     }
/* 380 */     log();
/* 381 */     return rs;
/*     */   }
/*     */   
/*     */   public int executeUpdate(String sql) throws SQLException {
/* 385 */     this.mSql = sql;
/* 386 */     startTimer();
/* 387 */     int numRows = 0;
/*     */     try {
/* 389 */       this.mStmt.executeUpdate(sql);
/*     */     } catch (SQLException e) {
/* 391 */       logException(e);
/* 392 */       processDbError(e);
/* 393 */       throw e;
/*     */     }
/* 395 */     log();
/* 396 */     return numRows;
/*     */   }
/*     */   
/*     */   public boolean execute(String sql) throws SQLException {
/* 400 */     this.mSql = sql;
/* 401 */     startTimer();
/* 402 */     boolean result = false;
/*     */     try {
/* 404 */       this.mStmt.execute(sql);
/*     */     } catch (SQLException e) {
/* 406 */       logException(e);
/* 407 */       processDbError(e);
/* 408 */       throw e;
/*     */     }
/* 410 */     log();
/* 411 */     return result;
/*     */   }
/*     */   
/*     */   public int[] executeBatch() throws SQLException {
/* 415 */     startTimer();
/*     */     int[] result;
/*     */     try {
/* 418 */       result = this.mStmt.executeBatch();
/*     */     } catch (SQLException e) {
/* 420 */       logException(e);
/* 421 */       processDbError(e);
/* 422 */       throw e;
/*     */     }
/* 424 */     log();
/* 425 */     return result;
/*     */   }
/*     */   
/*     */   public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
/* 429 */     startTimer();
/*     */     int numRows;
/*     */     try {
/* 432 */       numRows = this.mStmt.executeUpdate(sql, autoGeneratedKeys);
/*     */     } catch (SQLException e) {
/* 434 */       logException(e);
/* 435 */       processDbError(e);
/* 436 */       throw e;
/*     */     }
/* 438 */     log();
/* 439 */     return numRows;
/*     */   }
/*     */   
/*     */   public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
/* 443 */     startTimer();
/*     */     int numRows;
/*     */     try {
/* 446 */       numRows = this.mStmt.executeUpdate(sql, columnIndexes);
/*     */     } catch (SQLException e) {
/* 448 */       logException(e);
/* 449 */       processDbError(e);
/* 450 */       throw e;
/*     */     }
/* 452 */     log();
/* 453 */     return numRows;
/*     */   }
/*     */   
/*     */   public int executeUpdate(String sql, String[] columnNames) throws SQLException {
/* 457 */     startTimer();
/*     */     int numRows;
/*     */     try {
/* 460 */       numRows = this.mStmt.executeUpdate(sql, columnNames);
/*     */     } catch (SQLException e) {
/* 462 */       logException(e);
/* 463 */       processDbError(e);
/* 464 */       throw e;
/*     */     }
/* 466 */     log();
/* 467 */     return numRows;
/*     */   }
/*     */   
/*     */   public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
/* 471 */     startTimer();
/*     */     boolean result;
/*     */     try {
/* 474 */       result = this.mStmt.execute(sql, autoGeneratedKeys);
/*     */     } catch (SQLException e) {
/* 476 */       logException(e);
/* 477 */       processDbError(e);
/* 478 */       throw e;
/*     */     }
/* 480 */     log();
/* 481 */     return result;
/*     */   }
/*     */   
/*     */   public boolean execute(String sql, int[] columnIndexes) throws SQLException {
/* 485 */     startTimer();
/*     */     boolean result;
/*     */     try {
/* 488 */       result = this.mStmt.execute(sql, columnIndexes);
/*     */     } catch (SQLException e) {
/* 490 */       logException(e);
/* 491 */       processDbError(e);
/* 492 */       throw e;
/*     */     }
/* 494 */     log();
/* 495 */     return result;
/*     */   }
/*     */   
/*     */   public boolean execute(String sql, String[] columnNames) throws SQLException {
/* 499 */     startTimer();
/*     */     boolean result;
/*     */     try {
/* 502 */       result = this.mStmt.execute(sql, columnNames);
/*     */     } catch (SQLException e) {
/* 504 */       logException(e);
/* 505 */       processDbError(e);
/* 506 */       throw e;
/*     */     }
/* 508 */     log();
/* 509 */     return result;
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/db/DebugPreparedStatement.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */